﻿using AiQiuQuan.Sport.Core;
using AiQiuQuan.Sport.Model.Enums;
using AiQiuQuan.Sport.WebApi.Entities;
using AiQiuQuan.Sport.WebApi.Repositories;
using Microsoft.EntityFrameworkCore;

namespace AiQiuQuan.Sport.WebApi.HangfireServices
{
    /// <summary>
    /// 教练预约定时任务
    /// </summary>
    [ReccuringJobCron("0 0/30 * * * ?")]
    public class CoacherBookingHangfireService : IHangfireService
    {
        private readonly ICoacherBookRepository _coacherBookRepository;
        private readonly IUnitOfWorkManager _unitOfWorkManager;
        private readonly ICoacherStudentRepository _coacherStudentRepository;
        private readonly ICoacherStudentRecordRepository _coacherStudentRecordRepository;

        /// <summary>
        /// ctor
        /// </summary>
        public CoacherBookingHangfireService(
            IUnitOfWorkManager unitOfWorkManager,
            ICoacherBookRepository coacherBookRepository,
            ICoacherStudentRepository coacherStudentRepository,
            ICoacherStudentRecordRepository coacherStudentRecordRepository)
        {
            _unitOfWorkManager = unitOfWorkManager;
            _coacherBookRepository = coacherBookRepository;
            _coacherStudentRepository = coacherStudentRepository;
            _coacherStudentRecordRepository = coacherStudentRecordRepository;
        }

        /// <summary>
        /// 执行
        /// </summary>
        public async Task ExecuteAsync()
        {
            var date = DateTimeOffset.Now.Date;
            var time = new TimeSpan(DateTimeOffset.Now.Hour, DateTimeOffset.Now.Minute, 0);
            var list = await _coacherBookRepository.AsNoTracking()
                .Where(m => m.State == CoacherBookStateEnum.Processing && m.BookDate <= date)
                .ToListAsync();
            list = list.Where(m => m.BookDate < date || time >= TimeSpan.Parse(m.EndTime)).ToList();
            if (list.Any())
            {
                //点名操作
                foreach (var book in list.GroupBy(m => new { m.BusinessId, m.StartTime, m.EndTime }))
                {
                    var start = TimeSpan.Parse(book.Key.StartTime);
                    var end = TimeSpan.Parse(book.Key.EndTime);
                    var studentList = new List<CoacherStudent>();
                    var recordList = new List<CoacherStudentRecord>();
                    foreach (var item in book)
                    {
                        var student = await _coacherStudentRepository.FirstOrDefaultAsync(m => m.CoacherUserId == item.CoacherUserId && m.UserId == item.UserId);
                        if (student != null)
                        {
                            var timesCount = (decimal)(end - start).TotalHours / 1.0M;
                            timesCount = student.TimesCount - timesCount >= 0 ? timesCount : student.TimesCount;
                            if (timesCount > 0)
                            {
                                student.TimesCount -= timesCount;
                                var record = new CoacherStudentRecord
                                {
                                    CoacherUserId = student.CoacherUserId,
                                    CoacherId = student.CoacherId,
                                    UserId = student.UserId,
                                    ChangeCount = -timesCount,
                                    TimesCount = student.TimesCount,
                                    OperateType = CourseRecordOperateTypeEnum.Call,
                                    Remark = "点名"
                                };
                                studentList.Add(student);
                                recordList.Add(record);
                            }
                        }
                    }

                    using (var uow = _unitOfWorkManager.Begin())
                    {
                        var builder = await _coacherBookRepository.UpdatePartialAsync();
                        await builder.Set(m => m.State, CoacherBookStateEnum.Finished).Where(m => m.BusinessId == book.Key.BusinessId).ExecuteAsync();
                        foreach (var student in studentList)
                        {
                            await _coacherStudentRepository.UpdateAsync(student);
                        }

                        if (recordList.Any())
                        {
                            await _coacherStudentRecordRepository.BulkAddAsync(recordList);
                        }

                        await uow.CompleteAsync();
                    }
                }
            }

            //删除今天前的教练预约数据
            await _coacherBookRepository.DeleteAsync(m => m.BookDate < date);
        }
    }
}
